package william.stack;

import javax.naming.OperationNotSupportedException;
import java.util.Stack;

/**
 * @author ZhangShenao
 * @date 2024/1/15
 * @description <a href="https://leetcode.cn/problems/implement-queue-using-stacks/description/">...</a>
 */
public class Leetcode232_用栈实现队列 {
    /**
     * 通过两个栈实现:一个输入栈in,一个输出栈out
     * 当元素入队时,将元素直接压栈至输入栈
     * 当元素出队时,从输出栈中弹栈
     * 如果输出栈为空,则需要将输入栈中的元素依次弹栈,并压栈至输出栈中
     */
    class MyQueue {
        /**
         * 输入栈
         */
        private Stack<Integer> in;

        /**
         * 输出栈
         */
        private Stack<Integer> out;

        public MyQueue() {
            //初始化输入栈和输出栈
            in = new Stack<>();
            out = new Stack<>();
        }

        public void push(int x) {
            //入队操作,将元素直接压栈至输入栈
            in.push(x);
        }

        public int pop() {
            //判断队列是否为空
            if (empty()) {
                throw new RuntimeException("queue is empty!!");
            }
            //如果输出栈为空,则将输入栈中的元素依次压栈到输出栈中
            if (out.empty()) {
                in2Out();
            }

            //出队操作,从输出栈中弹栈
            return out.pop();
        }

        public int peek() {
            //判断队列是否为空
            if (empty()) {
                throw new RuntimeException("queue is empty!!");
            }
            //如果输出栈为空,则将输入栈中的元素依次压栈到输出栈中
            if (out.empty()) {
                in2Out();
            }

            //获取输出栈栈顶的元素
            return out.peek();
        }

        public boolean empty() {
            //判断输入、输出栈是否同时为空
            return (in.empty() && out.empty());
        }

        /**
         * 将输入栈中的元素依次压栈至输出栈中
         */
        private void in2Out() {
            while (!in.empty()) {
                out.push(in.pop());
            }
        }
    }
}
